﻿using Mysoft.Common.Enum;
using Mysoft.Common.Response;
using Mysoft.Entity.Basic;
using System.Linq.Expressions;

namespace Mysoft.Data.Repository
{
    /// <summary>
    /// 
    /// </summary>
    public interface IRepository<TEntity> where TEntity : EntityBase
    {
        #region dbcontext同步
        /// <summary>
        /// 添加一个对象
        /// </summary>
        /// <param name="entities"></param>
        TEntity Add(TEntity entities);

        /// <summary>
        /// 添加多个对象
        /// </summary>
        /// <param name="entities"></param>
        void AddRange(IEnumerable<TEntity> entities);

        /// <summary>
        /// 删除一个对象
        /// </summary>
        /// <param name="entities"></param>
        void Delete(TEntity entities);

        /// <summary>
        /// 删除多个对象
        /// </summary>
        /// <param name="entities"></param>
        void Delete(IEnumerable<TEntity> entities);

        /// <summary>
        /// 删除一个对象
        /// </summary>
        /// <param name="entities"></param>
        void Delete(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// 修改一个对象
        /// </summary>
        /// <param name="entities"></param>
        void Modify(TEntity entities);

        /// <summary>
        /// 获取一个对象
        /// </summary>
        /// <param name="id">Id</param>
        /// <returns>对象实例</returns>
        TEntity FindFirst(Guid id);
        /// <summary>
        /// 根据条件获取一个对象
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        TEntity FindFirst(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// 根据条件获取
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        List<TEntity> Find(Expression<Func<TEntity, bool>> predicate);


        /// <summary>
        /// AsNoTracking
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
         IQueryable<TEntity> FindAsNoTracking(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        ///判断是否存在
        /// </summary>
        /// <returns></returns>
        public bool Any(Expression<Func<TEntity, bool>> predicate);


        /// <summary>
        /// 分页排序
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pagesize"></param>
        /// <param name="rowcount"></param>
        /// <param name="orderBy"></param>
        /// <returns></returns>
        IQueryable<TEntity> IQueryablePage(Expression<Func<TEntity, bool>> predicate, int pageIndex, int pagesize, out int rowcount, Dictionary<string, QueryOrderBy> orderBy, bool returnRowCount = true);


        /// <summary>
        /// 根据表达式返回IQueryable 
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        IQueryable<TEntity> FindAsIQueryable(Expression<Func<TEntity, bool>> predicate);
        #endregion

        #region dbcontext 异步


        /// <summary>
        /// AsNoTracking
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        Task<List<TEntity>> FindAsNoTrackingAsync(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// 根据条件异步获取单个对象
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        Task<TEntity?> FindAsyncFirst(Expression<Func<TEntity, bool>> predicate);
        /// <summary>
        /// 根据条件异步获取集合
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        Task<List<TEntity>> FindAsync(Expression<Func<TEntity, bool>> predicate);
        /// <summary>
        /// 异步添加一个对象
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        Task<TEntity> AddAsync(TEntity entities);

        /// <summary>
        /// 异步添加多个
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        Task AddRangeAsync(IEnumerable<TEntity> entities);
        #endregion

        #region bulk
        /// <summary>
        /// 批量新增
        /// </summary>
        /// <param name="entities"></param>
        void BulkAddRange(IList<TEntity> entities);

        /// <summary>
        /// 提交
        /// </summary>
        int Commit();

        /// <summary>
        /// 异步批量新增
        /// </summary>
        /// <param name="entities"></param>
        Task BulkAddRangeAsync(IList<TEntity> entities);

        /// <summary>
        /// 批量修改
        /// </summary>
        /// <param name="entities">需要传入完整实体,不传的字段就会被更新为空</param>
        void BulkUpdate(IList<TEntity> entities);

        /// <summary>
        /// 异步批量修改
        /// </summary>
        /// <param name="entities">需要传入完整实体,不传的字段就会被更新为空</param>
        Task BulkUpdateAsync(IList<TEntity> entities);
        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="entities"></param>
        void BulkDelete(IList<TEntity> entities);

        /// <summary>
        /// 异步批量删除
        /// </summary>
        /// <param name="entities"></param>
        Task BulkDeleteAsync(IList<TEntity> entities);
        #endregion

        #region 事务
        ResponseContent BeginTransaction(Func<ResponseContent> func, System.Data.IsolationLevel IsolationLevel = System.Data.IsolationLevel.ReadUncommitted);

        #endregion
        }
}
